<?php

namespace app\core\services\user;

use app\core\entities\User;
use app\core\forms\user\PasswordResetRequestForm;
use app\core\forms\user\ResetPasswordForm;
use app\core\repositories\user\UserRepository;
use RuntimeException;
use Yii;
use yii\base\Exception;
use yii\mail\MailerInterface;

class PasswordResetService
{
    private MailerInterface $mailer;
    private UserRepository $users;

    public function __construct(UserRepository $users, MailerInterface $mailer)
    {
        $this->mailer = $mailer;
        $this->users = $users;
    }

    public function request(PasswordResetRequestForm $form): void
    {
        $user = $this->users->getByEmail($form->email);

        if (!$user->isActive()) {
            throw new \DomainException(Yii::t('auth', 'User is not active.'));
        }

        $user->requestPasswordReset();
        $this->users->save($user);

        $sent = $this->mailer
            ->compose(
                ['html' => 'auth/reset/confirm-html', 'text' => 'auth/reset/confirm-text'],
                ['user' => $user]
            )
            ->setFrom(\Yii::$app->params['adminEmail'])
            ->setTo($user->email)
            ->setSubject(Yii::t('main', '{name} - Password reset', [
                'name' => Yii::$app->params['settings']['site']['name']
            ], 'ru'))
            ->send();

        if (!$sent) {
            throw new RuntimeException('Sending error.');
        }
    }

    public function validateToken($token): void
    {
        if (empty($token) || !is_string($token)) {
            throw new \DomainException('Password reset token cannot be blank.');
        }
        if (!$this->users->existsByPasswordResetToken($token)) {
            throw new \DomainException('Wrong password reset token.');
        }
    }

    public function reset(string $token, ResetPasswordForm $form): void
    {
        $user = $this->users->getByPasswordResetToken($token);
        $user->resetPassword($form->password);
        $this->users->save($user);
    }

    /**
     * @throws Exception
     */
    public function smartReset(string $token): void
    {
        $password = Yii::$app->security->generateRandomString(10);
        $user = $this->users->getByPasswordResetToken($token);
        $user->resetPassword($password);
        $user->generateAuthKey();
        $this->users->save($user);

        $mailer = $this->mailer;
        $mailer->htmlLayout = "layouts/ego-3-html";

//        $signer = null;
//        if (isset(Yii::$app->params['dkim_key']) && isset(Yii::$app->params['dkim_domain']) && isset(Yii::$app->params['dkim_selector'])) {
//            $signer = new \Swift_Signers_DKIMSigner(Yii::$app->params['dkim_key'], Yii::$app->params['dkim_domain'], Yii::$app->params['dkim_selector']);
//        }

        $message = $mailer
            ->compose(
                ['html' => 'auth/reset/v3/reset-html', 'text' => 'auth/reset/v3/reset-text'],
                ['user' => $user, 'password' => $password]
            )
            ->setTo($user->email)
            ->setFrom(Yii::$app->params['senderEmail'])
            ->setSubject('Новый пароль - ' . Yii::$app->params['settings']['site']['name']);

        //if ($signer) {
        //    $message->getSwiftMessage()->attachSigner($signer);
        //}
        $sent = $message->send();

        if (!$sent) {
            throw new RuntimeException('Email sending error.');
        }
    }

    public function smartResetRequest(User $user): void
    {
        // send mail
        $user->requestPasswordReset();
        $this->users->save($user);

        $mailer = $this->mailer;
        $mailer->htmlLayout = "layouts/ego-3-html";

//        $signer = null;
//        if (isset(Yii::$app->params['dkim_key']) && isset(Yii::$app->params['dkim_domain']) && isset(Yii::$app->params['dkim_selector'])) {
//            $signer = new \Swift_Signers_DKIMSigner(Yii::$app->params['dkim_key'], Yii::$app->params['dkim_domain'], Yii::$app->params['dkim_selector']);
//        }

        $message = $mailer
            ->compose(
                ['html' => 'auth/reset/v3/confirm-html', 'text' => 'auth/reset/v3/confirm-text'],
                ['user' => $user]
            )
            ->setFrom(Yii::$app->params['senderEmail'])
            ->setTo($user->email)
            ->setSubject('Сброс пароля - ' . Yii::$app->params['settings']['site']['name']);

//        if ($signer) {
//            $message->getSwiftMessage()->attachSigner($signer);
//        }
        $sent = $message->send();

        if (!$sent) {
            throw new RuntimeException('Sending error.');
        }
    }
}
